package com.isunny.mode.tactics.factory;

import com.isunny.mode.tactics.strategy.EvictionStrategy;
import com.isunny.mode.tactics.EvictionType;
import com.isunny.mode.tactics.strategy.FifoEvictionStrategy;
import com.isunny.mode.tactics.strategy.LfuEvictionStrategy;
import com.isunny.mode.tactics.strategy.LruEvictionStrategy;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * 单例工厂
 *
 * @author luom
 * @date 2022/2/25
 */
public class EvictionStrategyLoopFactory {

    private static final List<EvictionRange> EVICTION_STRATEGY_List = new ArrayList<>();

    static {
        EVICTION_STRATEGY_List.add(new EvictionRange(EvictionType.FIFO, FifoEvictionStrategy.class));
        EVICTION_STRATEGY_List.add(new EvictionRange(EvictionType.LFU, LfuEvictionStrategy.class));
        EVICTION_STRATEGY_List.add(new EvictionRange(EvictionType.LRU, LruEvictionStrategy.class));
    }

    private EvictionStrategyLoopFactory() {
    }

    /**
     * 策略工厂
     *
     * @param eviction 策略名
     * @return EvictionStrategy
     */
    public static EvictionStrategy clientSelect(String eviction) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        EvictionStrategy evictionStrategy = null;
        for (EvictionRange evictionRange : EVICTION_STRATEGY_List) {
            if (evictionRange.select(eviction)) {
                Class<EvictionStrategy> evictionStrategyClass = evictionRange.getEvictionStrategyClass();
                Constructor<EvictionStrategy> constructor = evictionStrategyClass.getConstructor();
                evictionStrategy = constructor.newInstance();
                break;
            }
        }
        return evictionStrategy;
    }
}
